#ifndef LECTEUR_H
#define	LECTEUR_H

#include <string>
#include <vector>
#include <stdlib.h>

#include "LecteurSymbole.h"
#include "Symbole.h"
#include "TableSymboles.h"
#include "Arbre.h"

using namespace std;

class Lecteur {
    
public:
    Lecteur(LecteurSymbole * ls);
    // Construit un lecteur
    Lecteur();
    
    // Accesseurs
    inline TableSymboles getTs ()    { return ts;    }
    inline Noeud*        getArbre () { return arbre; }
    
    inline LecteurSymbole* getLs() { return this->ls; }
    inline void setLs(LecteurSymbole * ls) { this->ls = ls; }
    
    
protected:
    LecteurSymbole * ls; // le lecteur de symboles utilisé pour analyser le fichier
    Noeud* arbre;
    TableSymboles ts;
    
    // implémentation de la grammaire
    Noeud* expression();          //  <expression>   ::= <terme> { <opAdd> <terme> }
    Noeud* terme();               //  <terme>        ::= <facteur> { <opMult> <facteur> }
    virtual Noeud* facteur() = 0;     //  Dépend du lecteur : programme ou fonction
    Symbole opAdd();              //  <opAdd>        ::= + | -
    Symbole opMult();             //  <opMult>       ::= * | /
    Noeud* expBool();             //  <expBool>      ::= <termeBool> { ou <termeBool> }
    Noeud* termeBool();           //  <termeBool>    ::= <relation> { et <relation> }
    Noeud* relation();            //  <relation>     ::= <expression> { <opRel> <expression> }
    Symbole opRel();              //  <opRel>        ::= == | != | < | <= | > | >=
    Symbole opUnaire();           //  <opUnaire>     ::= - | non
    
    // outils pour se simplifier l'analyse syntaxique
    void testerSymCour (string ch);  // si symbole courant != ch, erreur : on arrete le programme, sinon rien
    void sauterSymCour (string ch);  // si symbole courant == ch, on passe au symbole suivant, sinon erreur : on arrete
    void erreur (string mess);      // affiche les message d'erreur mess et arrete le programme
};






#endif	/* LECTEURPROGRAMME_H */

